package kontrol;

import java.awt.event.KeyEvent;
import view.ViewHUD;
import view.ViewViewPort;
import model.interfaces.selectable.ControllablePlayer;
import java.util.Map;
import java.util.Hashtable;

/**
 *
 * @author kagioglu
 */
public class ViewportInterpreter implements KeyInterpreter
{
    private interface ViewportRunnable
    {
        void run( ViewportManager manager );
    }

    private ViewportManager manager;
    private Map<Integer, ViewportRunnable> keymap;
    private Map<Integer, ViewportRunnable> cntrlkeymap;
    
    public ViewportInterpreter
    (
        KeyEventRouter router,
        ControllablePlayer cplayer,
        ViewHUD hud,
        ViewViewPort viewport
    )
    {
        this.manager = new ViewportManager( cplayer, hud, viewport );
        this.initializeKeymap(router);
    }

    private void initializeKeymap( KeyEventRouter router )
    {
        class GroupUp implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollGroupUp();
            }
        }

        class GroupDown implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollGroupDown();
            }
        }

        class TypeUp implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollTypeUp();
            }
        }

        class TypeDown implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollTypeDown();
            }
        }

        class InstanceUp implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollInstanceUp();
            }
        }

        class InstanceDown implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollInstanceDown();
            }
        }

        class CommandUp implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollCommandUp();
            }
        }

        class CommandDown implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.scrollCommandDown();
            }
        }

        class CreateNewRallyPoint implements ViewportRunnable
        {
            private final int newID;
            public CreateNewRallyPoint( int newID )
            {
                this.newID = newID;
            }
            public void run( ViewportManager manager )
            {
                manager.createNewRallyPoint(this.newID);
            }
        }

        class CenterOnSelected implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.centerOnSelectedInstance();
            }
        }

        class SetDirectionExecute implements ViewportRunnable
        {
            private final int numpad;
            public SetDirectionExecute( int numpad )
            {
                this.numpad = numpad;
            }
            public void run( ViewportManager manager )
            {
                manager.setArg(this.numpad);
                manager.addCommand();
            }
        }

        class SetArmyExecute implements ViewportRunnable
        {
            private final int armyID;
            public SetArmyExecute( int armyID )
            {
                this.armyID = armyID;
            }
            public void run( ViewportManager manager )
            {
                manager.setArg(this.armyID);
                manager.addCommand();
            }
        }

        class Execute implements ViewportRunnable
        {
            public void run( ViewportManager manager )
            {
                manager.addCommand();
            }
        }

        class OpenUnitOverview implements ViewportRunnable
        {
            private KeyEventRouter router;
            public OpenUnitOverview( KeyEventRouter router )
            {
                this.router = router;
            }
            public void run( ViewportManager manager )
            {
                this.router.switchToUnitOverviewInterpreter();
            }
        }

        class OpenStructureOverview implements ViewportRunnable
        {
            private KeyEventRouter router;
            public OpenStructureOverview( KeyEventRouter router )
            {
                this.router = router;
            }
            public void run( ViewportManager manager )
            {
                this.router.switchToStructureOverviewInterpreter();
            }
        }

        this.keymap = new Hashtable<Integer, ViewportRunnable>();
        this.cntrlkeymap = new Hashtable<Integer, ViewportRunnable>();
        
        this.cntrlkeymap.put(KeyEvent.VK_UP, new GroupUp());
        this.cntrlkeymap.put(KeyEvent.VK_DOWN, new GroupDown());
        this.cntrlkeymap.put(KeyEvent.VK_LEFT, new TypeUp());
        this.cntrlkeymap.put(KeyEvent.VK_RIGHT, new TypeDown());

        this.keymap.put(KeyEvent.VK_UP, new InstanceUp());
        this.keymap.put(KeyEvent.VK_DOWN, new InstanceDown());
        this.keymap.put(KeyEvent.VK_LEFT, new CommandUp());
        this.keymap.put(KeyEvent.VK_RIGHT, new CommandDown());

        this.cntrlkeymap.put(KeyEvent.VK_1, new CreateNewRallyPoint(1));
        this.cntrlkeymap.put(KeyEvent.VK_2, new CreateNewRallyPoint(2));
        this.cntrlkeymap.put(KeyEvent.VK_3, new CreateNewRallyPoint(3));
        this.cntrlkeymap.put(KeyEvent.VK_4, new CreateNewRallyPoint(4));
        this.cntrlkeymap.put(KeyEvent.VK_5, new CreateNewRallyPoint(5));
        this.cntrlkeymap.put(KeyEvent.VK_6, new CreateNewRallyPoint(6));
        this.cntrlkeymap.put(KeyEvent.VK_7, new CreateNewRallyPoint(7));
        this.cntrlkeymap.put(KeyEvent.VK_8, new CreateNewRallyPoint(8));
        this.cntrlkeymap.put(KeyEvent.VK_9, new CreateNewRallyPoint(9));
        this.cntrlkeymap.put(KeyEvent.VK_0, new CreateNewRallyPoint(0));

        this.cntrlkeymap.put(KeyEvent.VK_NUMPAD5, new CenterOnSelected());

        this.keymap.put(KeyEvent.VK_NUMPAD1, new SetDirectionExecute(1));
        this.keymap.put(KeyEvent.VK_NUMPAD2, new SetDirectionExecute(2));
        this.keymap.put(KeyEvent.VK_NUMPAD3, new SetDirectionExecute(3));
        this.keymap.put(KeyEvent.VK_NUMPAD4, new SetDirectionExecute(4));
        //no 5
        this.keymap.put(KeyEvent.VK_NUMPAD6, new SetDirectionExecute(6));
        this.keymap.put(KeyEvent.VK_NUMPAD7, new SetDirectionExecute(7));
        this.keymap.put(KeyEvent.VK_NUMPAD8, new SetDirectionExecute(8));
        this.keymap.put(KeyEvent.VK_NUMPAD9, new SetDirectionExecute(9));

        this.keymap.put(KeyEvent.VK_1, new SetArmyExecute(1));
        this.keymap.put(KeyEvent.VK_2, new SetArmyExecute(2));
        this.keymap.put(KeyEvent.VK_3, new SetArmyExecute(3));
        this.keymap.put(KeyEvent.VK_4, new SetArmyExecute(4));
        this.keymap.put(KeyEvent.VK_5, new SetArmyExecute(5));
        this.keymap.put(KeyEvent.VK_6, new SetArmyExecute(6));
        this.keymap.put(KeyEvent.VK_7, new SetArmyExecute(7));
        this.keymap.put(KeyEvent.VK_8, new SetArmyExecute(8));
        this.keymap.put(KeyEvent.VK_9, new SetArmyExecute(9));
        this.keymap.put(KeyEvent.VK_0, new SetArmyExecute(0));

        this.keymap.put(KeyEvent.VK_ENTER, new Execute());

        this.keymap.put(KeyEvent.VK_U, new OpenUnitOverview(router));
        this.keymap.put(KeyEvent.VK_S, new OpenStructureOverview(router));
    }
    
    public void interpret( KeyEvent event )
    {
        Map<Integer, ViewportRunnable> temp;
        if(event.isControlDown())
        {
            temp = this.cntrlkeymap;
        }
        else
        {
            temp = this.keymap;
        }
        temp.get(event.getKeyCode()).run(this.manager);
    }

    public void gameTick()
    {
        this.manager.refresh();
    }
}
